Introduce system_state variable.
authorKeir Fraser <keir@xen.org>
Thu, 22 Mar 2012 12:20:13 +0000 (12:20 +0000)
committerKeir Fraser <keir@xen.org>
Thu, 22 Mar 2012 12:20:13 +0000 (12:20 +0000)
Use it to replace x86-specific early_boot boolean variable.

Also use it to detect suspend/resume case during cpu offline/online
to avoid unnecessarily breaking vcpu and cpupool affinities.

Signed-off-by: Keir Fraser <keir@xen.org>
Acked-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
xen/arch/arm/setup.c
xen/arch/x86/acpi/power.c
xen/arch/x86/mm.c
xen/arch/x86/setup.c
xen/arch/x86/x86_32/mm.c
xen/arch/x86/x86_64/mm.c
xen/common/cpupool.c
xen/common/kernel.c
xen/common/schedule.c
xen/include/asm-x86/setup.h
xen/include/xen/kernel.h

index 777f8fb144c9c471b1490a0044ede6cd8dbd7ff7..551c1496e259a21703f0e9ddfe6493fd19257d5f 100644 (file)
@@ -253,6 +253,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Hide UART from DOM0 if we're using it */
     serial_endboot();
 
+    system_state = SYS_STATE_active;
+
     domain_unpause_by_systemcontroller(dom0);
 
     /* Switch on to the dynamically allocated stack for the idle vcpu
index 4b242043c82c5e9cdda36ebbab7978b88ca39dcd..9e1f98904f40c4023734c7ef7b8d8a1dcdc10779 100644 (file)
@@ -135,6 +135,9 @@ static int enter_state(u32 state)
     if ( !spin_trylock(&pm_lock) )
         return -EBUSY;
 
+    BUG_ON(system_state != SYS_STATE_active);
+    system_state = SYS_STATE_suspend;
+
     printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state);
 
     freeze_domains();
@@ -142,7 +145,10 @@ static int enter_state(u32 state)
     acpi_dmar_reinstate();
 
     if ( (error = disable_nonboot_cpus()) )
+    {
+        system_state = SYS_STATE_resume;
         goto enable_cpu;
+    }
 
     cpufreq_del_cpu(0);
 
@@ -159,6 +165,7 @@ static int enter_state(u32 state)
     if ( (error = device_power_down()) )
     {
         printk(XENLOG_ERR "Some devices failed to power down.");
+        system_state = SYS_STATE_resume;
         goto done;
     }
 
@@ -179,6 +186,8 @@ static int enter_state(u32 state)
         break;
     }
 
+    system_state = SYS_STATE_resume;
+
     /* Restore CR4 and EFER from cached values. */
     cr4 = read_cr4();
     write_cr4(cr4 & ~X86_CR4_MCE);
@@ -212,6 +221,7 @@ static int enter_state(u32 state)
     mtrr_aps_sync_end();
     acpi_dmar_zap();
     thaw_domains();
+    system_state = SYS_STATE_active;
     spin_unlock(&pm_lock);
     return error;
 }
index 006e37f3cfc2165bb0ecfa5ec2b0a6956dc65fa6..6d81f98d8349603279140a02625adba4826b6cf6 100644 (file)
@@ -5316,7 +5316,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
 
 void free_xen_pagetable(void *v)
 {
-    if ( early_boot )
+    if ( system_state == SYS_STATE_early_boot )
         return;
 
     if ( is_xen_heap_page(virt_to_page(v)) )
index 49f91ab543e758de703db97145afe8f3669e47eb..bd218593a7f48f10230658c9646403d16db3dc6a 100644 (file)
@@ -81,8 +81,6 @@ boolean_param("noapic", skip_ioapic_setup);
 s8 __read_mostly xen_cpuidle = -1;
 boolean_param("cpuidle", xen_cpuidle);
 
-bool_t __read_mostly early_boot = 1;
-
 cpumask_t __read_mostly cpu_present_map;
 
 unsigned long __read_mostly xen_phys_start;
@@ -271,7 +269,7 @@ static void *__init bootstrap_map(const module_t *mod)
     void *ret;
 
 #ifdef __x86_64__
-    if ( !early_boot )
+    if ( system_state != SYS_STATE_early_boot )
         return mod ? mfn_to_virt(mod->mod_start) : NULL;
 #endif
 
@@ -1168,7 +1166,7 @@ void __init __start_xen(unsigned long mbi_p)
 #endif
 
     end_boot_allocator();
-    early_boot = 0;
+    system_state = SYS_STATE_boot;
 
 #if defined(CONFIG_X86_64)
     vesa_init();
@@ -1391,6 +1389,8 @@ void __init __start_xen(unsigned long mbi_p)
 
     dmi_end_boot();
 
+    system_state = SYS_STATE_active;
+
     domain_unpause_by_systemcontroller(dom0);
 
     reset_stack_and_jump(init_done);
index fd145979da545af029018f437ae2dd49770c5e29..37efa3c1def89bd563f066a8e28011fbf523b6aa 100644 (file)
@@ -43,7 +43,7 @@ void *alloc_xen_pagetable(void)
 {
     unsigned long mfn;
 
-    if ( !early_boot )
+    if ( system_state != SYS_STATE_early_boot )
     {
         void *v = alloc_xenheap_page();
 
index 59cd00822b38dc32c3078fc5155c2a7cd3bcd10f..6a71c2860efdd8403057c20c74a410294c9e073c 100644 (file)
@@ -85,7 +85,7 @@ void *alloc_xen_pagetable(void)
 {
     unsigned long mfn;
 
-    if ( !early_boot )
+    if ( system_state != SYS_STATE_early_boot )
     {
         struct page_info *pg = alloc_domheap_page(NULL, 0);
 
index 6cef4a003ece51623ea4b15894d9dccc143519a6..c9cc123a40667203e8ac483cf4dca2cb51401461 100644 (file)
@@ -629,6 +629,10 @@ static int cpu_callback(
     unsigned int cpu = (unsigned long)hcpu;
     int rc = 0;
 
+    if ( (system_state == SYS_STATE_suspend) ||
+         (system_state == SYS_STATE_resume) )
+        goto out;
+
     switch ( action )
     {
     case CPU_DOWN_FAILED:
@@ -642,6 +646,7 @@ static int cpu_callback(
         break;
     }
 
+out:
     return !rc ? NOTIFY_DONE : notifier_from_errno(rc);
 }
 
index 88984d2355e258d428861fafddb5027438bed0cd..1679dbb4f219e6a1315d8ef4299a9d4f3cac6e0a 100644 (file)
@@ -20,6 +20,8 @@
 
 #ifndef COMPAT
 
+enum system_state system_state = SYS_STATE_early_boot;
+
 int tainted;
 
 xen_commandline_t saved_cmdline;
index 24f89467a17ef31bdbfb3b9af224c871bd835968..a1eeac36eb49f0af6309bf1e31b9106a9297fa11 100644 (file)
@@ -538,7 +538,7 @@ int cpu_disable_scheduler(unsigned int cpu)
     int    ret = 0;
 
     c = per_cpu(cpupool, cpu);
-    if ( c == NULL )
+    if ( (c == NULL) || (system_state == SYS_STATE_suspend) )
         return ret;
 
     for_each_domain_in_cpupool ( d, c )
index b983c97773f2d04aa552f4aebcf951ad879ebc66..4a16302b5319b33e50a8f57f2120d5aef58bb265 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <xen/multiboot.h>
 
-extern bool_t early_boot;
 extern unsigned long xenheap_initial_phys_start;
 
 void early_cpu_init(void);
index 92de4285b300c8fe8cb2245194ec14a95131a93b..b74cc4ff0dddda6be258fb2abce99cadf8b1cf06 100644 (file)
@@ -87,5 +87,13 @@ extern char _sinittext[], _einittext[];
     (__p >= _sinittext) && (__p < _einittext);  \
 })
 
+extern enum system_state {
+    SYS_STATE_early_boot,
+    SYS_STATE_boot,
+    SYS_STATE_active,
+    SYS_STATE_suspend,
+    SYS_STATE_resume
+} system_state;
+
 #endif /* _LINUX_KERNEL_H */